
package controller.game;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import model.Model;
import model.entity.door.Door;
import model.entity.floor.Floor;
import model.entity.shop.Shop;
import model.entity.stairs.Stairs;
import model.prop.gem.Gem;
import model.prop.key.Key;
import model.prop.medicine.Medicine;
import model.prop.weapon.Knife;
import model.prop.weapon.Weapon;
import model.role.monster.Monster;
import model.role.npc.Npc;
import model.role.player.Player;
import model.window.MapData;
import view.entity.DoorView;
import view.entity.FloorView;
import view.role.PlayerView;
import view.window.HintPopUpView;
import view.window.InofView;
import view.window.MainView;
import view.window.MapView;
import view.window.PopUpView;

public class GameListener implements KeyListener {

	private Model[][] mapData;

	private MapView mapView;

	private Player player;

	private PlayerView playerView;

	private MainView mainView;

	private InofView inofView;

	public GameListener(MainView mainView, Model[][] mapData, MapView mapView, Player player, InofView inofView) {
		this.inofView = inofView;
		this.mapData = mapData;
		this.mapView = mapView;
		this.player = player;
		this.mainView = mainView;
		this.playerView = new PlayerView(player.getType());
		mapView.remove(player.getX() + player.getY() * 11);
		mapView.add(playerView, player.getX() + player.getY() * 11);
		mainView.setVisible(true);
	}

	@Override
	public void keyTyped(KeyEvent e) {
	}

	@Override
	public void keyReleased(KeyEvent e) {

	}

	@Override
	public void keyPressed(KeyEvent e) {
		vip(e);
		Move(e);
	}

	/**
	 * vip模式
	 */
	private void vip(KeyEvent e) {
		if(e.isControlDown() && e.isShiftDown()) {
			if(player.isVip()) {
				player.setVip(false);
				player.setAttack(player.getAttack() - 10000);
				player.setDefense(player.getDefense() - 10000);
				inofView.update();
				mainView.setVisible(true);
				HintPopUpView.show(mainView, new Dimension(250, 150),
						new String[] { "VIP模式已关闭", "长路漫漫，请保重" },120);
			}else {
				player.setVip(true);
				player.addAttack(10000);
				player.addDefense(10000);
				inofView.update();
				mainView.setVisible(true);
				HintPopUpView.show(mainView, new Dimension(250, 150),
						new String[] { "已开启VIP模式", "开始愉快的玩耍把" },120);
			}
		}
	}

	/**
	 * 移动要做的事
	 */
	private void Move(KeyEvent e) {
		int x = player.getX(), y = player.getY();

		if (e.getKeyChar() == 'w' || e.getKeyChar() == 'W' || e.getKeyCode() == KeyEvent.VK_UP) {
			if (y != 0)
				y--;
			playerView.start(PlayerView.UP);
		} else if (e.getKeyChar() == 's' || e.getKeyChar() == 'S' || e.getKeyCode() == KeyEvent.VK_DOWN) {
			if (y != 10)
				y++;
			playerView.start(PlayerView.DOWN);
		} else if (e.getKeyChar() == 'a' || e.getKeyChar() == 'A' || e.getKeyCode() == KeyEvent.VK_LEFT) {
			if (x != 0)
				x--;
			playerView.start(PlayerView.LEFT);
		} else if (e.getKeyChar() == 'd' || e.getKeyChar() == 'D' || e.getKeyCode() == KeyEvent.VK_RIGHT) {
			if (x != 10)
				x++;
			playerView.start(PlayerView.RIGHT);
		}
		// 普通方块的验证
		contact(x, y);
		// 刷新楼层验证
		if (mapData[y][x].getType() == Stairs.STAIRS_TYPE_UP || mapData[y][x].getType() == Stairs.STAIRS_TYPE_DOWN) {
			updateFloor();
		}
		inofView.update();
		mainView.setVisible(true);
	}

	/**
	 * 人物接触格子
	 */
	private void contact(int x, int y) {
		if (mapData[y][x].contact(player)) {
			// 可以通过时
			Component component = mapView.getComponent(x + y * 11);
			if (mapData[y][x] instanceof Door) {
				mapData[y][x] = Floor.floor;
				inofView.update();
				mainView.setVisible(true);
				((DoorView) component).show();
				return;
			}
			mapView.remove(playerView);
			mapView.add(new FloorView(), player.getX() + player.getY() * 11);
			mapView.remove(x + y * 11);
			mapView.add(playerView, x + y * 11);
			player.setCoord(x, y);

			// 显示提示
			showInof(x, y);
			if (mapData[y][x].getType() != Stairs.STAIRS_TYPE_DOWN_BIRTH
					&& mapData[y][x].getType() != Stairs.STAIRS_TYPE_UP_BIRTH) {
				mapData[y][x] = Floor.floor;
				player.getMapDataList().get(player.getNowFloor() - 1)[y][x] = 0;
			}
		} else {
			noEntryInof(x, y);
		}

	}

	/**
	 * 不能通行的网格提示
	 */
	private void noEntryInof(int x, int y) {
		if (mapData[y][x] instanceof Monster) {// 打不过怪物时
			Monster monster = (Monster) mapData[y][x];
			HintPopUpView.show(mainView, new Dimension(250, 150),
					new String[] { monster.getName() + "有点强大", "这次就先放过他吧" }, 120);
		} else if (mapData[y][x] instanceof Shop) {
			shop();
		} else if (mapData[y][x] instanceof Npc) {
			npc(x, y);
		} else if (mapData[y][x] instanceof Door) {
			HintPopUpView.show(mainView, new Dimension(250, 150), new String[] { "有道门挡住了路", "你需要相应的钥匙" }, 120);
		}
	}

	/**
	 * 对npc处理
	 */
	private void npc(int x, int y) {
		if (mapData[y][x].getType() == Npc.NPC_TYPE_DIALOGUE) {
			HintPopUpView.show(mainView, new Dimension(250, 150), new String[] { "小伙子，你好啊", "你见过我的兄弟吗" }, 120);
		} else if (mapData[y][x].getType() == Npc.NPC_TYPE_MERCHANT) {
			PopUpView upView = new PopUpView(mainView, "提升能力需要20经验", new Dimension(450, 380), 120,
					new String[] { "20点攻击", "20点防御", "取消" });
			upView.addButtonsListener(new ActionListener[] { ee -> {
				upView.dispose();
				mainView.setVisible(true);
				if (player.getExp() < 20) {
					HintPopUpView.show(mainView, new Dimension(250, 150), new String[] { "提升能力需要20经验", "刷点怪再来吧" }, 120);
				} else {
					player.addAttack(20);
					player.setExp(player.getExp() - 20);
					inofView.update();
					mainView.setVisible(true);
					HintPopUpView.show(mainView, new Dimension(250, 150), new String[] { "提升攻击成功", "欢迎下次再来" }, 120);
				}
			}, ee -> {
				upView.dispose();
				mainView.setVisible(true);
				if (player.getExp() < 20) {
					HintPopUpView.show(mainView, new Dimension(250, 150), new String[] { "提升能力需要20经验", "刷点怪再来吧" }, 120);
				} else {
					player.addDefense(20);
					player.setExp(player.getExp() - 20);
					inofView.update();
					mainView.setVisible(true);
					HintPopUpView.show(mainView, new Dimension(250, 150), new String[] { "提升防御成功", "欢迎下次再来" }, 120);
				}
				upView.dispose();
				mainView.setVisible(true);
			}, ee -> upView.dispose() });
			upView.setVisible(true);
		}
	}

	/**
	 * 购买商品
	 */
	private void shop() {
		PopUpView upView = new PopUpView(mainView, "每次购买需要20金币", new Dimension(450, 450), 120,
				new String[] { player.getNowFloor() * 25 + "生命值", player.getNowFloor() * 2 + "攻击力",
						player.getNowFloor() + "防御力", "取消" });
		upView.addButtonsListener(new ActionListener[] { ee -> {
			upView.dispose();
			if (player.getMoney() < 20) {
				HintPopUpView.show(mainView, new Dimension(250, 150), new String[] { "购买商品需要20金币", "攒点钱再来吧" }, 120);
			} else {
				player.setRed(player.getRed() + player.getNowFloor() * 25);
				player.setMoney(player.getMoney() - 20);
				inofView.update();
				mainView.setVisible(true);
				HintPopUpView.show(mainView, new Dimension(250, 150), new String[] { "购买血量成功", "欢迎下次再来" }, 120);
			}
		}, ee -> {
			upView.dispose();
			if (player.getMoney() < 20) {
				HintPopUpView.show(mainView, new Dimension(250, 150), new String[] { "购买商品需要20金币", "攒点钱再来吧" }, 120);
			} else {
				player.addAttack(player.getNowFloor() * 2);
				player.setMoney(player.getMoney() - 20);
				inofView.update();
				mainView.setVisible(true);
				HintPopUpView.show(mainView, new Dimension(250, 150), new String[] { "购买攻击力成功", "欢迎下次再来" }, 120);
			}
			upView.dispose();
		}, ee -> {
			upView.dispose();
			if (player.getMoney() < 20) {
				HintPopUpView.show(mainView, new Dimension(250, 150), new String[] { "购买商品需要20金币", "攒点钱再来吧" }, 120);
			} else {
				player.addDefense(player.getNowFloor());
				player.setMoney(player.getMoney() - 20);
				inofView.update();
				mainView.setVisible(true);
				HintPopUpView.show(mainView, new Dimension(250, 150), new String[] { "购买防御力成功", "欢迎下次再来" }, 120);
			}
		}, ee -> upView.dispose(), });
		upView.setVisible(true);
	}

	/**
	 * 显示提示
	 */
	private void showInof(int x, int y) {
		inofView.update();
		mainView.setVisible(true);
		if (mapData[y][x] instanceof Gem) {
			boolean isRed = mapData[y][x].getType() == Gem.GEM_TYPE_RED;
			HintPopUpView.show(mainView, new Dimension(250, 150), new String[] { isRed ? "恭喜获得红宝石" : "恭喜获得蓝宝石",
					(isRed ? "攻击" : "防御") + "增加" + player.getNowFloor() + "点" }, 120);

		} else if (mapData[y][x] instanceof Key) {
			String string = null;
			switch (mapData[y][x].getType()) {
			case Key.KEY_TYPE_BLUE:
				string = "恭喜获得蓝钥匙";
				break;
			case Key.KEY_TYPE_YELLOW:
				string = "恭喜获得黄钥匙";
				break;
			case Key.KEY_TYPE_RED:
				string = "恭喜获得红钥匙";
				break;
			}
			HintPopUpView.show(mainView, new Dimension(250, 150), new String[] { string, "请谨慎使用钥匙" }, 120);
		} else if (mapData[y][x] instanceof Medicine) {
			boolean isRed = Medicine.MEDICINE_TYPE_RED == mapData[y][x].getType();
			HintPopUpView
					.show(mainView, new Dimension(250, 150),
							new String[] { (isRed ? "恭喜获得红药水" : "恭喜获得蓝药水"),
									("血量增加" + (isRed ? (player.getNowFloor() * 50) : (player.getNowFloor() * 200))) },
							120);
		} else if (mapData[y][x] instanceof Weapon) {
			Weapon weapon = (Weapon) mapData[y][x];
			HintPopUpView.show(mainView, new Dimension(250, 150), new String[] { "恭喜获得" + weapon.getName(),
					(weapon instanceof Knife ? "攻击力增加" : "防御力增加") + weapon.getValue(), }, 120);
		} else if (mapData[y][x] instanceof Monster) {
			Monster monster = (Monster) mapData[y][x];
			HintPopUpView.show(
					mainView, new Dimension(250, 275), new String[] { "你击败了" + monster.getName(),
							"损失血量" + monster.getNo_red(), "获得经验" + monster.getExp() + ",获得金币" + monster.getMoney() },
					120);
		}
	}

	/**
	 * 刷新楼层
	 */
	private void updateFloor() {
		mapView = new MapView(player.getMapDataList().get(player.getNowFloor() - 1));
		mainView.getContentPane().remove(0);
		mainView.getContentPane().add(mapView, 0);
		mapData = MapData.getMapData(player.getMapDataList().get(player.getNowFloor() - 1));
		mapView.remove(player.getX() + player.getY() * 11);
		mapView.add(playerView, player.getX() + player.getY() * 11);
		inofView.update();
		playerView.start(PlayerView.DOWN);
	}

}
